package cn.gson.financial.kernel.service.impl;

import cn.gson.financial.kernel.constans.ComprehensiveParamesConstans;
import cn.gson.financial.kernel.constans.ContansConfig;
import cn.gson.financial.kernel.service.WxService;
import cn.gson.financial.kernel.utils.HttpClientUtils;
import cn.gson.financial.kernel.utils.IdCreateUtil;
import cn.gson.financial.kernel.utils.RedisCacheManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Component
@Transactional(rollbackFor = Throwable.class)
@Service
public class WxServiceImpl implements WxService {
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RedisCacheManager redisCacheManager;
    @Resource
    private RedisTemplate redisTemplate;
    @Value("${redis.wx.jsapi.ticket}")
    private String jsApiTicket;


    private static final Logger logger = LoggerFactory.getLogger(WxServiceImpl.class);

	public String getAccessToken() {
	    String key = ContansConfig.redis_wx_access_token;

		String getAccessTokenUrl = ContansConfig.getAccessTokenUrl;
        //从redis缓存中获取token
        if(redisCacheManager.hasKey(key)){
            System.out.println("从redis缓存中获取token :"+ (String) redisCacheManager.get(key));
            return (String) redisCacheManager.get(key);
        }

        String appId = ContansConfig.WX_APPID;
        String secret = ContansConfig.WX_SECRET;

        String url = String.format(getAccessTokenUrl,appId,secret);
        logger.info("获取accessToken的url===:"+url);
        ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
        logger.info("获取Atoken的result===" + result.toString());
        if(result.getStatusCode()== HttpStatus.OK){
            JSONObject jsonObject = JSON.parseObject(result.getBody());
            String access_token = jsonObject.getString("access_token");
            Long expires_in = jsonObject.getLong("expires_in");
            logger.info("access_token===" + access_token);
            logger.info("expires_in===" + expires_in);
           //缓存toekn到redis
           redisCacheManager.set(key,access_token,expires_in);
           return access_token;
        }
        return null;
	}

    public String getAccessToken1() {
	    return "";
    }

	public Map<String, Object> getQrCode() {
         String url = String.format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s",getAccessToken());
         logger.info("getQrCode:"+url);
         //String json = "{\"expire_seconds\": 120, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"fxy\"}}}";
        String json = "";
        if(ContansConfig.SELECT_ACTIVE){
            json = "{\"expire_seconds\": 120, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\":\"" + ContansConfig.PRD +"\"}}}";
        }else {
            json = "{\"expire_seconds\": 120, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\":\"" + ContansConfig.TEST + "\"}}}";
        }

         logger.info("getQrCode中json====" + json);
		 ResponseEntity<String> result = restTemplate.postForEntity(url,json , String.class);
         logger.info("二维码:"+result.getBody());
         JSONObject jsonObject = JSON.parseObject(result.getBody());
         Map<String,Object> map=new HashMap<String,Object>();
         map.put("ticket",jsonObject.getString("ticket"));
         map.put("url",jsonObject.getString("url"));
         if("40001".equals(jsonObject.getString("errcode"))){
             logger.info("accToken失效!redisKey中任然存在,清除redisKey并重新获取accToken");
             String key = ContansConfig.redis_wx_access_token;
             redisCacheManager.delete(key);
             map = getQrCode();
         }
         logger.info("获取二维码结果map====" + map);
         return map;
	}

    @Override
    public Map<String,String> getSignature(String url){
        String jsapi_ticket = getJsApiTicket();

        String noncestr = IdCreateUtil.createInvitationCode();
//        String url="http://pretty.zsmarter.com/invoice-m.html";
        String timestamp = IdCreateUtil.createTaskId();

        String signature = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
        signature = DigestUtils.sha1Hex(signature);

        Map<String,String> map = new HashMap<>();
        map.put("noncestr", noncestr);
        map.put("timestamp", timestamp);
        map.put("signature", signature);
        map.put("appid", ContansConfig.WX_APPID);
        return map;
    }

    public String getJsApiTicket() {
        //先去 redis中 获取 jsApi_ticket, 如果没有在去 获取
//        String key = smartT_wx_jsapi_ticket;
        String key = jsApiTicket;
        if(redisCacheManager.hasKey(key)){
            return (String) redisCacheManager.get(key);
        }
        String acToken = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+acToken+"&type=jsapi";
        String result = HttpClientUtils.httpGet(url);
        logger.info("获取jsAPI_ticket_result:"+result);
        JSONObject jsonObject = JSON.parseObject(result);
        if(jsonObject.getString("errcode").equals("0")){
            String ticket = jsonObject.getString("ticket");
            logger.info("获取jsAPI_ticket: " + ticket);
            String timeOut = jsonObject.getString("expires_in");
            //存入redis ....
            redisCacheManager.set(key, ticket, Integer.parseInt(timeOut));
            return ticket;
        }
        return jsonObject.getString("errmsg");
    }

}
